#ifndef GAMETD_CONFIGMANAGER_H
#define GAMETD_CONFIGMANAGER_H

#include <SDL.h>
#include <string>
#include <fstream>
#include <sstream>
#include <iostream>
#include <http_content.h>
#include "Map.h"
#include "Wave.h"
#include "Manager.h"

using json = hv::Json;

class ConfigManager : public Manager<ConfigManager> {
    friend class Manager<ConfigManager>;

public:

    struct BasicTemplate {
        std::string window_title = "GameTd";
        int window_width = 1280;
        int window_height = 720;
    };

    struct PlayerTemplate {
        double speed = 3;
        double normal_attack_interval = 0.5;
        double normal_attack_damage = 0;
        double skill_interval = 10;
        double skill_damage = 1;
    };

    struct TowerTemplate {
        std::vector<double> interval{};
        std::vector<double> damage{};
        std::vector<double> view_range{};
        std::vector<double> cost{};
        std::vector<double> upgrade_cost{};
    };

    struct EnemyTemplate {
        double hp = 100;
        double speed = 1;
        double damage = 1;
        double reward_ratio = 0.5;
        double recover_interval = 10;
        double recover_range = 0;
        double recover_intensity = 25;
    };

public:
    Map map;
    std::vector<Wave> waveList{};

    int level_archer = 0; // 弓箭手等级
    int level_axeman = 0; // 斧头兵等级
    int level_gunner = 0; // 炮手等级

    bool is_game_win = true;
    bool is_game_over = false;
    SDL_Rect rectTileMap = {0};

    BasicTemplate basic_template;

    PlayerTemplate player_template;

    TowerTemplate archer_template;
    TowerTemplate axeman_template;
    TowerTemplate gunner_template;

    EnemyTemplate slim_template;
    EnemyTemplate king_slim_template;
    EnemyTemplate skeleton_template;
    EnemyTemplate goblin_template;
    EnemyTemplate goblin_priest_template;

    const double num_initial_hp = 10;
    const double num_initial_coin = 100;
    const double num_coin_per_prop = 10;

public:
    bool LoadGameConfig(const std::string& path);
    bool LoadLevelConfig(const std::string& path);

private:
    ConfigManager() = default;
    ~ConfigManager() = default;
    void LoadGameConfigBasic(json& root);
    void LoadGameConfigPlayer(json& root);
    void LoadGameConfigTower(json& root);
    void LoadGameConfigTowerOne(json& node, TowerTemplate &towerTemplate);
    void LoadGameConfigEnemy(json& root);
    void LoadGameConfigEnemyOne(json& node, EnemyTemplate &towerTemplate);
    static void ParseJsonArray(std::vector<double>& vec, json& arrJson);
};


#endif //GAMETD_CONFIGMANAGER_H
